Advanced Operations

Tag Event Reporting

This feature can be used to enable reporting tag visibility changes. If a reader supports this feature it reports the Reader Capability isTagEventReportingSupported as true. The following code snippet enabled reporting tags when a Tag is visible/Gone out of Visibility/Back to visibility for at least 100 ms;

  

TriggerInfo triggerInfo = new TriggerInfo();

triggerInfo.setEnableTagEventReport(true);

triggerInfo.TagEventReportInfo.setReportNewTagEvent(TAG_EVENT_REPORT_TRIGGER.MODERATED);

triggerInfo.TagEventReportInfo.setReportTagInvisibleEvent(TAG_EVENT_REPORT_TRIGGER.MODERATED);

triggerInfo.TagEventReportInfo.setReportTagBackToVisibilityEvent( TAG_EVENT_REPORT_TRIGGER.MODERATED);

triggerInfo.TagEventReportInfo.setNewTagEventModeratedTimeoutMilliseconds((short)100);

triggerInfo.TagEventReportInfo.setTagInvisibleEventModeratedTimeoutMilliseconds((short)100);

triggerInfo.TagEventReportInfo.setTagBackToVisibilityModeratedTimeoutMilliseconds((short)100);

reader.Actions.Inventory.perform(null, triggerInfo, null);

  

TAG_EVENT reported as part of TAG_DATA indicates the visibility state of the Tag.

 

Using Pre-Filters

Pre-filters are same as the Select command of C1G2 specification. Once applied, pre-filters are applied prior to Inventory and Access operations.

Introduction

Singulation

Singulation refers to the method of identifying an individual Tag in a multiple-Tag environment. RFID Readers could support State-Aware or State-Unaware pre-filtering (or singulation) which is indicated by the boolean flag IsTagInventoryStateAwareSingulationSupported in the ReaderCapabilities class.

In order to filter tags that match a specific condition, it is necessary to use the tag-sessions and their states (setting the tags to different states based on match criteria- reader.Actions.PreFilters.add) so that while performing inventory, tags can be instructed to participate (singulation - reader.Config.Antennas.setSingulationControl) or not participate in the inventory based on their states.

Sessions and Inventoried Flags

Tags provide 4 sessions (denoted S0, S1, S2, and S3) and maintain an independent inventoried flag for each session. Each of the four inventoried flags has two values, denoted A and B. These inventoried flag of each session can be set to A or B based on match criteria using method reader.Actions.PreFilters.add.

Selected Flag

Tags provide a selected flag, SL, which can be asserted or deasserted based on match criteria using method reader.Actions.PreFilters.add

State-Unaware Singulation

In state-unaware singulation the Reader permits 6 options (as enumerated by STATE_UNAWARE_ACTION) of filtering tags. This is more simplified than state-aware singulation.

Option Description
STATE_UNAWARE_ACTION_SELECT_NOT_UNSELECT Matching tags: SELECT , Non-matching tags: UNSELECT
STATE_UNAWARE_ACTION_SELECT Matching tags: SELECT, Non-matching tags: do nothing
STATE_UNAWARE_ACTION_NOT_UNSELECT Matching tags: do nothing, Non-matching tags: UNSELECT
STATE_UNAWARE_ACTION_UNSELECT Matching tags: UNSELECT , Non-matching tags: do nothing
STATE_UNAWARE_ACTION_UNSELECT_NOT_SELECT Matching tags: UNSELECT , Non-matching tags: SELECT
 STATE_UNAWARE_ACTION_NOT_SELECT Matching tags: do nothing, Non-matching tags: SELECT

 

State-Aware Singulation

In state-aware singulation the Application can specify detailed controls for singulation: Action and Target.

Action indicates whether matching Tags assert or deassert SL (Selected Flag), or set their inventoried flag to A or to B. Tags conforming to the match criteria specified using the method reader.Actions.PreFilters.Add are considered matching and the remaining are non-matching.

Target indicates whether to modify a Tag’s SL flag or its inventoried flag, and in the case of inventoried it further specifies one of four sessions.

Session Description
SESSION_S0 S0
SESSION_S1 S1
SESSION_S2 S2
SESSION_S3 S3

 

Truncate Action

Truncate action specifies whether a Tag backscatters its entire EPC, or only that portion of the EPC immediately following Mask. During truncated replies a Tag substitutes 00000 for the PC bits. Truncated replies are always followed by the CRC-16 in EPC memory 00h to 0Fh; a Tag does not re compute this CRC for a truncated reply.

Applying Pre-Filters

The following are the steps to use pre-filters:

Add pre-filters

Each RFID Reader supports a maximum number of Pre-Filters per Antenna as indicated by reader.ReaderCapabilites.getMaxNumPreFilters which can be known using the ReaderCapabilities.

The application can set pre-filters using reader.Actions.PreFilters.add and remove using reader.Actions.PreFilters.delete.

State-Unaware Singulation

// Add state unaware pre-filter

PreFilters filters = new PreFilters();

PreFilters.PreFilter filter = filters.new PreFilter();

byte[] tagMask = new byte[] { 0x12, 0x11 };

filter.setAntennaID((short)3);// Set this filter for Antenna ID 3

filter.setTagPattern(tagMask);// Tags which starts with 0x1211

filter.setTagPatternBitCount(tagMask.length * 8);

filter.setBitOffset(32); // skip PC bits (always it should be in bit length)

filter.setMemoryBank(MEMORY_BANK.MEMORY_BANK_EPC);

filter.setFilterAction(FILTER_ACTION.FILTER_ACTION_STATE_UNAWARE); // use state unaware singulation

filter.StateUnawareAction.setStateUnawareAction(STATE_UNAWARE_ACTION.STATE_UNAWARE_ACTION_UNSELECT);  // do not select the tags that match the pre-filter criteria

reader.Actions.PreFilters.add(filter);

State-Aware Singulation

// Add state aware pre-filter

PreFilters filters = new PreFilters();

PreFilters.PreFilter filter = filters.new PreFilter();

byte[] tagMask = new byte[] { 0x12, 0x11 };

filter.setAntennaID((short)3);// Set this filter for Antenna ID 3

filter.setTagPattern(tagMask);// Tags which starts with 0x1211

filter.setTagPatternBitCount(tagMask.length * 8);

filter.setBitOffset(32); // skip PC bits (always it should be in bit length)

filter.setMemoryBank(MEMORY_BANK.MEMORY_BANK_EPC);

filter.setFilterAction(FILTER_ACTION.FILTER_ACTION_STATE_AWARE); // use state aware singulation

filter.StateAwareAction.setTarget(TARGET.TARGET_INVENTORIED_STATE_S1); // inventoried flag of session S1 of matching tags to B

filter.StateAwareAction.setStateAwareAction(STATE_AWARE_ACTION.STATE_AWARE_ACTION_INV_B; // not to select tags that match the criteria

reader.Actions.PreFilters.add(filter);

// It is also required to set appropriate singulation control not to

// get tags with inventoried flag B for session 1

Set appropriate singulation controls

Now that the pre-filters are set (i.e. Tags are classified into matching or non-matching criteria), the Application needs to specify which tags should participate in the Inventory using reader.Config.Antennas.setSingulationControl(). Singulation Control must be specified with respect to each Antenna like Pre-Filters.  

State-Unaware Singulation

// Set the singulation control

SingulationControl s1_singulationControl = reader.Config.Antennas.getSingulationControl(1);

s1_singulationControl.setSession(SESSION.SESSION_S1); // Set session to operate on S1. If not specified, reader uses its own way of implementing the state-unware singulation

reader.Config.Antennas.setSingulationControl(1, s1_singulationControl);

State-Aware Singulation

// Set the singulation control

SingulationControl s1_singulationControl = reader.Config.Antennas.getSingulationControl(1);

s1_singulationControl.setSession(SESSION.SESSION_S1);

s1_singulationControl.Action.setInventoryState(INVENTORY_STATE.INVENTORY_STATE_B);

s1_singulationControl.Action.setSLFlag(SL_FLAG.SL_FLAG_DEASSERTED);

s1_singulationControl.Action.setPerformStateAwareSingulationAction(true);

reader.Config.Antennas.setSingulationControl(1, s1_singulationControl);

Perform Inventory or Access operation

Inventory or Access operation when performed after setting pre-filters, will use the tags filtered out of pre-filters for their operation.

Using Triggers

Triggers are the conditions that should be satisfied in order to start or stop an operation (Inventory or Access Sequence). This information can be specified using TriggerInfo class. The application can also configure the Tag-Report trigger which indicates when to receive ‘n’ unique Tag-Reports from the Reader.

The following are some use-cases of using TRIGGER_INFO:

  1. GPI based Inventory – Start inventory when GPI port ‘n’ changes state to ‘TRUE’ and stop inventory when GPI port ‘n’ changes state to ‘FALSE’.

TriggerInfo triggerInfo = new TriggerInfo();

// start trigger GPI port 1 changes to true

triggerInfo.StartTrigger.setTriggerType(START_TRIGGER_TYPE.START_TRIGGER_TYPE_GPI);

triggerInfo.StartTrigger.GPI.setPortNumber(1);

triggerInfo.StartTrigger.GPI.setGPIEvent(true);

// stop trigger GPI port 1 changes to false

triggerInfo.StopTrigger.setTriggerType(STOP_TRIGGER_TYPE.STOP_TRIGGER_TYPE_GPI_WITH_TIMEOUT);

triggerInfo.StopTrigger.GPI.setPortNumber(1);

triggerInfo.StopTrigger.GPI.setGPIEvent(false);

triggerInfo.StopTrigger.GPI.setTimeout(1000); // 1 sec

// report back each tag report as and when it is read by Reader

triggerInfo.setTagReportTrigger(1);

  1. Periodic Inventory – Start inventory at a specified time for a specified duration repeatedly.

TriggerInfo triggerInfo = new TriggerInfo();

// start inventory on 12th of this month and 12am and runs 200 milliseconds of every 2 seconds

triggerInfo.StartTrigger.setTriggerType(START_TRIGGER_TYPE.START_TRIGGER_TYPE_PERIODIC);

triggerInfo.StartTrigger.Periodic.setPeriod(2000); // perform inventory for 2 seconds

// start time

SYSTEMTIME startTime = new SYSTEMTIME();

startTime.Day = 6;

startTime.Month = 8;

startTime.Year = 2011;

startTime.Hour = 9;

startTime.Minute = 20;

startTime.Second = 5;

triggerInfo.StartTrigger.Periodic.StartTime = startTime;

// stop trigger

triggerInfo.StopTrigger.setTriggerType(STOP_TRIGGER_TYPE.STOP_TRIGGER_TYPE_DURATION);

triggerInfo.StopTrigger.setDurationMilliSeconds(200); // stop after 200 milliseconds

// report back all read tags after completion of one round of inventory (i.e. one period)

triggerInfo.setTagReportTrigger(0);

  1. Perform ‘n’ Rounds of Inventory with a timeout – Start condition could be any; Stop condition is to perform ‘n’ rounds of inventory and then stop or stop inventory after the specified timeout.

TriggerInfo triggerInfo = new TriggerInfo();

// start inventory immediate

triggerInfo.StartTrigger.setTriggerType(START_TRIGGER_TYPE.START_TRIGGER_TYPE_IMMEDIATE);

// stop trigger

triggerInfo.StopTrigger.setTriggerType(STOP_TRIGGER_TYPE.STOP_TRIGGER_TYPE_N_ATTEMPTS_WITH_TIMEOUT);

triggerInfo.StopTrigger.NumAttempts.setN((short)3); // perform 3 rounds of inventory

triggerInfo.StopTrigger.NumAttempts.setTimeout(3000); // timeout after 3 seconds

// report back all read tags after 3 rounds of inventory

triggerInfo.setTagReportTrigger(0);

  1. Read ‘n’ Tags with a timeout – Start condition could be any; Stop condition is to stop after reading ‘n’ tags or stop inventory after the specified timeout.

    TriggerInfo triggerInfo = new TriggerInfo();

    // start inventory immediate

    triggerInfo.StartTrigger.setTriggerType(START_TRIGGER_TYPE.START_TRIGGER_TYPE_IMMEDIATE);

    // stop trigger

    triggerInfo.StopTrigger.setTriggerType(STOP_TRIGGER_TYPE.STOP_TRIGGER_TYPE_TAG_OBSERVATION_WITH_TIMEOUT);

    triggerInfo.StopTrigger.TagObservation.setN((short)100); // stop inventory after reading 100 tags

    triggerInfo.StopTrigger.TagObservation.setTimeout(3000); // timeout after 3 seconds

    // report back all read tags after getting 100 unique tags or after 3 seconds

    triggerInfo.setTagReportTrigger(0);

  2. Inventory based on Handheld Trigger – Start inventory when Handheld Gun/Button Trigger is pulled, and stop inventory when the Handheld Gun/Button Trigger is released or subject to timeout.

TriggerInfo triggerInfo = new TriggerInfo();

triggerInfo.StartTrigger.setTriggerType(START_TRIGGER_TYPE.START_TRIGGER_TYPE_HANDHELD);

// Start Inventory when the Handheld trigger is pressed

triggerInfo.StartTrigger.Handheld.setHandheldTriggerEvent(HANDHELD_TRIGGER_EVENT_TYPE.HANDHELD_TRIGGER_PRESSED);

triggerInfo.StopTrigger.setTriggerType(STOP_TRIGGER_TYPE.STOP_TRIGGER_TYPE_HANDHELD_WITH_TIMEOUT);

// Stop Inventory when the Handheld trigger is released

triggerInfo.StopTrigger.Handheld.setHandheldTriggerEvent(HANDHELD_TRIGGER_EVENT_TYPE.HANDHELD_TRIGGER_RELEASED);

triggerInfo.StopTrigger.Handheld.setHandheldTriggerTimeout(0);

reader.Actions.Inventory.perform(null, triggerInfo, null);

  1. Periodic Tag Reporting - Tags will be periodically reported on a specified timer interval elapsed. ReportTriggers takes precedence over TagReportTrigger property. In order to use setTagReportTrigger function, set the ReportTriggers.setPeriodicReportTrigger with value 0.

TriggerInfo triggerInfo = new TriggerInfo();

// Tags will be periodically reported in every 10 seconds

triggerInfo.ReportTriggers.setPeriodicReportTrigger(10);

  1. Extra Trigger - The support for array of start / stop triggers are added as extra triggers in TriggerInfo class. The field IsZebraTriggerSupported in ReaderCapabilities determines whether reader supports this feature or not. This allows to configure multiple start and start triggers. The reader internally pre-empts and execute the triggers when it meets the trigger condition. Reader supports maximum of seven extra triggers.

TriggerInfo triggerInfo = new TriggerInfo();

// Configure first pair of triggers

triggerInfo.StartTrigger.setTriggerType(START_TRIGGER_TYPE.START_TRIGGER_TYPE_GPI);

triggerInfo.StartTrigger.GPI.setPortNumber(1);

triggerInfo.StartTrigger.GPI.setGPIEvent(false);

triggerInfo.StartTrigger.GPI.setTimeout(0);

triggerInfo.StopTrigger.setTriggerType(STOP_TRIGGER_TYPE.STOP_TRIGGER_TYPE_GPI_WITH_TIMEOUT);

triggerInfo.StopTrigger.GPI.setPortNumber(1);

triggerInfo.StopTrigger.GPI.setGPIEvent(true);

triggerInfo.StopTrigger.GPI.setTimeout(0);

 

// Configure Extra Triggers

// 1. Start Trigger - Distance

ExtraTriggerInfo extra1 = triggerInfo.getExtraTriggerInfo(1);

extra1.StartTrigger.setTriggerType(START_TRIGGER_TYPE.START_TRIGGER_TYPE_DISTANCE);

extra1.StartTrigger.Distance.setDistance(5);

// 1. Stop Trigger - Time Lapse

extra1.StopTrigger.setTriggerType(STOP_TRIGGER_TYPE.STOP_TRIGGER_TYPE_TIMELAPSE);

extra1.StopTrigger.TimeLapse.setPeriodicDurationSeconds(50);

extra1.StopTrigger.TimeLapse.setTotalDurationSeconds(120);

 

// 2. Start Trigger - Time Lapse

ExtraTriggerInfo extra2 = triggerInfo.getExtraTriggerInfo(2);

extra2.StartTrigger.setTriggerType(START_TRIGGER_TYPE.START_TRIGGER_TYPE_TIMELAPSE);

extra2.StartTrigger.TimeLapse.StartTime = new TIMEOFDAY((short)15, (short)20, (short)5);

extra2.StartTrigger.TimeLapse.setPer**iod(50); // In 50 Seconds

// 2. Stop Trigger - Duration

extra2.StopTrigger.setTriggerType(STOP_TRIGGER_TYPE.STOP_TRIGGER_TYPE_DURATION);

extra2.StopTrigger.setDurationMilliSeconds(6000);

 

Inventory

Inventory with Triggers

There are various situations that act as conditions (triggers) for performing inventory.

Refer section “Using Triggers” to configure Triggers.

The following shows an example of performing 1 round of Inventory on Antennas 1 and 3.

TriggerInfo triggerInfo = new TriggerInfo();

// perform inventory on antenna 1 & 3

short[] antennaList = new short[] { 1, 3 };

AntennaInfo antennaInfo = new AntennaInfo(antennaList);

// start inventory immediate

triggerInfo.StartTrigger.setTriggerType(START_TRIGGER_TYPE.START_TRIGGER_TYPE_IMMEDIATE);

// stop trigger

triggerInfo.StopTrigger.setTriggerType(STOP_TRIGGER_TYPE.STOP_TRIGGER_TYPE_N_ATTEMPTS_WITH_TIMEOUT);

triggerInfo.StopTrigger.NumAttempts.setN((short)1); // perform 1 round of inventory

triggerInfo.StopTrigger.NumAttempts.setTimeout(0); // reader default timeout

// report back all read tags after 1 round of inventory

triggerInfo.setTagReportTrigger(0);

// perform inventory

reader.Actions.Inventory.perform(null, triggerInfo, antennaInfo);

Using Post-Filters

Post-filters are those filters which are applied on the Tags that the reader received through the pre-filters (if any).

Post-filters allow the application to set one or two tag patterns and to specify a condition as a combination of the patterns.

The following snippet shows setting a post-filter that does not get tags starting with 0x1122 and 0x2233.

PostFilter postFilter = new PostFilter();

byte[] tagMask = new byte[] { 0xff, 0xff };

// Tag Pattern A

postFilter.TagPatternA.setMemoryBank(MEMORY_BANK.MEMORY_BANK_EPC);

postFilter.TagPatternA.setTagPattern(new byte[] { 0x11, 0x22 });

postFilter.TagPatternA.setTagPatternBitCount(2 * 8);

postFilter.TagPatternA.setBitOffset(0);

postFilter.TagPatternA.setTagMask(tagMask);

postFilter.TagPatternA.setTagMaskBitCount(tagMask.length * 8);

// Tag Pattern B

postFilter.TagPatternB.setMemoryBank(MEMORY_BANK.MEMORY_BANK_EPC);

postFilter.TagPatternB.setTagPattern(new byte[] { 0x22, 0x33 });

postFilter.TagPatternB.setTagPatternBitCount(2 * 8);

postFilter.TagPatternB.setBitOffset(32); //skip PC

postFilter.TagPatternB.setTagMask(tagMask);

postFilter.TagPatternB.setTagMaskBitCount(tagMask.length * 8);

postFilter.setPostFilterMatchPattern(FILTER_MATCH_PATTERN.NOTA_AND_NOTB);

// perform inventory with post filter

reader.Actions.Inventory.perform(postFilter, null, null);

 

Using RSSI Filtering in Post Filters

Starting with version RFID_API3_5_1, applications can use RSSI based filtering if supported by the reader. This is indicated by the field IsRssiFilterSupported of ReaderCaps. The following code snippet does filtering of tags which have RSSI value in range -40 to -10.

PostFilter postFilter = new PostFilter();

postFilter.setRSSIRangeFilter( true);

postFilter.RssiRangeFilter.setMatchRange(MATCH_RANGE.WITHIN_RANGE);

postFilter.RssiRangeFilter.setPeakRSSILowerLimit((short)-40);

postFilter.RssiRangeFilter.setPeakRSSIUpperLimit((short)-10);

reader.Actions.Inventory.perform(postFilter, triggerInfo, null);

Access

Using Access-Filters

In order to perform an access operation on multiple tags, the Application can set ACCESS_FILTER to filter the required tags. If ACCESS_FILTER is not specified, the operation will be performed on all Tags. In any case, the PRE_FILTER(s) if any is set will apply prior to ACCESS_FILTER.

The following Access-filter gets all tags that have zeroed Reserved memory bank.

AccessFilter accessFilter = new AccessFilter();

byte[] tagMask = new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff };

// Tag Pattern A

accessFilter.TagPatternA.setMemoryBank(MEMORY_BANK.MEMORY_BANK_RESERVED);

accessFilter.TagPatternA.setTagPattern(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 });

accessFilter.TagPatternA.setTagPatternBitCount(8 * 8);

accessFilter.TagPatternA.setBitOffset(0);

accessFilter.TagPatternA.setTagMask(tagMask);

accessFilter.TagPatternA.setTagMaskBitCount(tagMask.length * 8);

 

accessFilter.setAccessFilterMatchPattern(FILTER_MATCH_PATTERN.A);

Access Operation on Multiple Tags

Performing a single Access operation on multiple tags is an asynchronous operation. The function issues the access-operation and returns. The Reader performs one round of inventory using pre-filters if any, and then applies the access-filters and the resultant tags are subject to the access-operation. When the access operation is complete, the API signals the eventStatusNotify event with event data as ACCESS_STOP_EVENT. The Application can call the method reader.Actions.TagAccess.getLastAccessResult to know the result. In case of Read access operation (reader.Actions.TagAccess.readEvent) the event eventReadNotify is signaled when Tags are reported.

The following snippet shows a sample write-access operation:

// Create Event to signify access operation complete

reader.Events.setAccessStartEvent(true);

reader.Events.setAccessStopEvent(true);

// Status Notification from the reader

class EventHandler implements RfidEventsListener {

  

        // Read Event Notification

        public void eventReadNotify(RfidReadEvents e){

            TagData tag = e.getReadEventData().tagData;

            System.out.println("Tag ID " + tag.getTagID());

  

            if (tag.getOpCode() == ACCESS_OPERATION_CODE.ACCESS_OPERATION_READ &&

                    tag.getOpStatus() == ACCESS_OPERATION_STATUS.ACCESS_SUCCESS)

            {

                if (tag.getMemoryBankData().length() > 0) {

                    System.out.println(" Mem Bank Data " + tag.getMemoryBankData());

                }

            }

  

        }

  

        // Status Event Notification

        public void eventStatusNotify(RfidStatusEvents e) {

            if (e.StatusEventData.getStatusEventType() == STATUS_EVENT_TYPE.ACCESS_START_EVENT) {

                // Access operation started

            }

            else if(e.StatusEventData.getStatusEventType() == STATUS_EVENT_TYPE.ACCESS_STOP_EVENT) {

                // Access operation stopped - Can be used to signal waiting thread

            }

        }

    }

// Access Filter - EPC ID starting with 0x1122

AccessFilter accessFilter = new AccessFilter();

byte[] tagMask = new byte[] { 0xff, 0xff };

// Tag Pattern A

accessFilter.TagPatternA.setMemoryBank(MEMORY_BANK.MEMORY_BANK_EPC);

accessFilter.TagPatternA.setTagPattern(new byte[] { 0x11, 0x22});

accessFilter.TagPatternA.setTagPatternBitCount(2 * 8);

accessFilter.TagPatternA.setBitOffset(0);

accessFilter.TagPatternA.setTagMask(tagMask);

accessFilter.TagPatternA.setTagMaskBitCount(tagMask.length * 8);

 

accessFilter.setAccessFilterMatchPattern(FILTER_MATCH_PATTERN.A);

 

// Write user memory bank data

TagAccess tagAccess = new TagAccess();

TagAccess.WriteAccessParams writeAccessParams = tagAccess.new WriteAccessParams();

byte[] writeData = new byte[4] { 0xff, 0xff, 0xff, 0xff };

writeAccessParams.setAccessPassword(0);

writeAccessParams.setMemoryBank(MEMORY_BANK.MEMORY_BANK_USER);

writeAccessParams.setByteOffset(0);

writeAccessParams.setWriteDataLength(writeData.length);

writeAccessParams.setWriteData(writeData);

// Asynchronous write operation

reader.Actions.TagAccess.writeEvent(writeAccessParams, accessFilter, null);

// wait for access operation to complete (ACCESS_STOP_EVENT will be signalled after completing the access operation in the eventStatusNotify)

 

// Get Access operation results

int[]successCount = new int[1];

int[]failureCount = new int[1];

reader.Actions.TagAccess.getLastAccessResult(successCount, failureCount);

Using Access Sequence

The Application can issue multiple access operations on a single go using Access-Sequence API. This is useful when each tag from a set of (access-filtered) tags is to be subject to an order of access operations.

The maximum number of access-operations that can be specified in an access sequence is available in reader.ReaderCapabilites.getMaxNumOperationsInAccessSequenceof ReaderCapabilities class.

The operations will be performed in the same order in which it is added to it sequence. An operation can be removed from the sequence using reader.Actions.TagAccess.OperationSequence.delete and finally de-initialized if no more needed by calling the function reader.Actions.TagAccess.OperationSequence.deleteAll().

// add Write Access operation - Write to User memory

TagAccess tagAccess = new TagAccess();

TagAccess.Sequence opSequence = tagAccess.new Sequence(tagAccess);

TagAccess.Sequence.Operation op1 = opSequence.new Operation();

op1.setAccessOperationCode(ACCESS_OPERATION_CODE.ACCESS_OPERATION_WRITE);

op1.WriteAccessParams.setMemoryBank(MEMORY_BANK.MEMORY_BANK_USER);

op1.WriteAccessParams.setAccessPassword(0);

op1.WriteAccessParams.setByteOffset(0);

op1.WriteAccessParams.setWriteData(new byte[] { (byte)0x55, (byte)0x66, (byte)0x77, (byte)0x88 });

op1.WriteAccessParams.setWriteDataLength(4);

reader.Actions.TagAccess.OperationSequence.add(op1);

// add Write Access operation - Write to Reserved memory bank

TagAccess.Sequence.Operation op2 = opSequence.new Operation();

op2.setAccessOperationCode(ACCESS_OPERATION_CODE.ACCESS_OPERATION_WRITE);

op2.WriteAccessParams.setMemoryBank(MEMORY_BANK.MEMORY_BANK_USER);

op2.WriteAccessParams.setAccessPassword(0);

op2.WriteAccessParams.setByteOffset(0);

op2.WriteAccessParams.setWriteData(new byte[] { (byte)0xBB, (byte)0xBB, (byte)0xBB, (byte)0xBB });

op2.WriteAccessParams.setWriteDataLength(4);

reader.Actions.TagAccess.OperationSequence.add(op2);

// perform access sequence

reader.Actions.TagAccess.OperationSequence.performSequence();

// wait for access operation complete

 

// get the access operation result

int[] successCount = new int[1];

int[] failureCount = new int[1];

reader.Actions.TagAccess.getLastAccessResult(successCount, failureCount);

// if the access operation is to be terminated without meeting stop trigger (if specified),

// stopSequence method can be called

reader.Actions.TagAccess.OperationSequence.stopSequence();